#include <iostream>
#include <fstream>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <chrono>

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int server_fd, new_socket;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    char buffer[BUFFER_SIZE] = {0};
    const char* filename = "received_tcp_file.bin";
    
    // 创建套接字
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }
    
    // 设置套接字选项
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }
    
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);
    
    // 绑定套接字
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }
    
    // 监听连接
    if (listen(server_fd, 3) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }
    
    std::cout << "TCP Server listening on port " << PORT << std::endl;
    
    // 接受连接
    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
        perror("accept");
        exit(EXIT_FAILURE);
    }
    
    std::ofstream file(filename, std::ios::binary);
    if (!file) {
        perror("file open failed");
        exit(EXIT_FAILURE);
    }
    
    auto start_time = std::chrono::high_resolution_clock::now();
    int bytes_received;
    size_t total_bytes = 0;
    
    // 接收文件
    while ((bytes_received = recv(new_socket, buffer, BUFFER_SIZE, 0)) > 0) {
        file.write(buffer, bytes_received);
        total_bytes += bytes_received;
    }
    
    auto end_time = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::seconds>(end_time - start_time).count();
    
    file.close();
    close(new_socket);
    close(server_fd);
    
    std::cout << "TCP File received successfully: " << total_bytes << " bytes in " 
              << duration << " seconds" << std::endl;
    if (duration > 0) {
        std::cout << "Effective transfer rate: " 
                  << (total_bytes / (1024.0 * 1024.0)) / duration << " MB/s" << std::endl;
    }
    
    return 0;
}    